package com.rokyinfo.common.utils;

import org.apache.commons.lang.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 操作日期的工具类
 * 
 * @author xuhuitao
 * @version: 1.0
 */
public final class DateUtils {
    /**
     * yyyy-MM-dd
     */
    public static final SimpleDateFormat YYYY_MM_DD = new SimpleDateFormat(
            "yyyy-MM-dd");
    public static final SimpleDateFormat YYYY_MM_DD_HH_MM_SS = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");
    /**
     * yyMM
     */
    public static final SimpleDateFormat YYMM = new SimpleDateFormat("yyMM");

    public static final int SUN_WEEK = 7;
    public static final int MON_WEEK = 1;
    public static final int TUE_WEEK = 2;
    public static final int WED_WEEK = 3;
    public static final int THU_WEEK = 4;
    public static final int FRI_WEEK = 5;
    public static final int SAT_WEEK = 6;

    /**
     * 每天24小时一共有的毫秒数
     */
    public static final long DAY_TIME_NUMBER = 1000 * 60 * 60 * 24;

    /**
     * 把日期类型转换成yyyy-MM-dd格式的字符串
     * 
     * @param date
     * @return
     */
    public static final String toString(Date date) {
        return YYYY_MM_DD.format(date);
    }

    /**
     * 返回当前的年份月份组成的字符串
     * 
     * @return
     */
    public static final String currentYYMM() {
        return YYMM.format(new Date(System.currentTimeMillis()));
    }

    /**
     * 把日期类型转换成yyyy-MM-dd mm:HH:ss格式的字符串
     * 
     * @return
     */
    public static final String format() {
        SimpleDateFormat sdf = new SimpleDateFormat(
                DateUtils.YYYY_MM_DD_HH_MM_SS.toPattern());
        return sdf.format(new Date());
    }

    /**
     * 把日期类型转换成yyyy-MM-dd格式的字符串
     * 
     * @param format
     * @return
     */
    public static final String format(String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date());
    }

    /**
     * 把日期类型转换成yyyy-MM-dd格式的字符串
     * 
     * @param format
     * @param date
     * @return
     */
    public static final String format(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    public static Date getDateByDayOfWeek(int dayOfWeek) {
        return DateUtils.getDateByDayOfWeek(dayOfWeek, Calendar.getInstance());
    }

    public static Date getDateByDayOfWeek(int dayOfWeek, Calendar calendar) {
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
        return calendar.getTime();
    }

    public static Date getFirstDateOfMonth(Calendar calendar) {
        calendar.set(Calendar.DAY_OF_MONTH,
                calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    public static Date getLastDateOfMonth(Calendar calendar) {
        calendar.set(Calendar.DAY_OF_MONTH,
                calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    public static Date getToday() {
        return org.apache.commons.lang.time.DateUtils.truncate(new Date(),
                Calendar.DATE);
    }

    public static boolean isOvertime(Date dualDate) {
        return DateUtils.isOvertime(dualDate, new Date());
    }

    public static boolean isOvertime(Date dualDate, Date destTag) {
        if (dualDate == null || destTag == null)
            return false;
        return (!org.apache.commons.lang.time.DateUtils.isSameDay(dualDate,
                destTag)) && destTag.after(dualDate);
    }

    public static Date getDateByDay(int numberOfDays) {
        return getDateByDay(new Date(), numberOfDays);
    }

    public static Date getDateByDay(Date date, int numberOfDays) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, numberOfDays);
        return calendar.getTime();
    }

    public static Date getDateByMonth(Date date, int numberOfMonths) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, numberOfMonths);
        return calendar.getTime();
    }

    public static Date getDateByYear(Date date, int numberOfYears) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, numberOfYears);
        return calendar.getTime();
    }

    /**
     * 根据日期格式，显示日期
     * 
     * @param date
     *            日期（完整的）
     * @param format
     *            格式化（例如：yyyy-MM-dd只显示年月日，或者HH:mm:ss只显示时分秒）
     * @return
     */
    public static String getDataStrByFormat(Date date, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        return simpleDateFormat.format(date);
    }

    /**
     * 根据年月日判断星期几，返回int，7=星期天，1=星期一
     * 
     * @param year
     *            年
     * @param month
     *            月
     * @param date
     *            日
     * @return
     */
    public static int getWeekByYMD(int year, int month, int date) {
        GregorianCalendar gc = new GregorianCalendar();
        final int[] kor_week = { SUN_WEEK, MON_WEEK, TUE_WEEK, WED_WEEK,
                THU_WEEK, FRI_WEEK, SAT_WEEK };
        gc.set(year, month - 1, date);
        int week = kor_week[gc.get(Calendar.DAY_OF_WEEK) - 1];
        return week;
    }

    /**
     * 根据日期字符创转换成对应格式的日期
     * 
     * @param dateTime
     * @param formatStr
     * @return
     * @throws ParseException
     */
    public static Date parseDate(String dateTime, String formatStr)
            throws ParseException {
        SimpleDateFormat format = null;
        format = new SimpleDateFormat("yyyy-MM-dd");
        if (!StringUtils.isEmpty(formatStr))
            format = new SimpleDateFormat(formatStr);
        Date date = format.parse(dateTime);
        return date;
    }

    /**
     * 获取给定日期的凌晨日期
     * 
     * @param date
     * 
     * @return 日期，例：2012-01-01 00:00:00
     * @throws ParseException
     */
    public static Date getDateStart(Date date) throws ParseException {

        Calendar calendar = Calendar.getInstance();
        Date currentDate = DateUtils.parseDate(
                DateUtils.format(date, YYYY_MM_DD.toPattern()),
                YYYY_MM_DD.toPattern());

        calendar.setTimeInMillis(currentDate.getTime());
        return calendar.getTime();
    }

    /**
     * 获取给定日期的午夜日期
     * 
     * @param date
     * 
     * @return 日期，例：2012-01-01 00:00:00
     * @throws ParseException
     */
    public static Date getDateEnd(Date date) throws ParseException {

        Calendar calendar = Calendar.getInstance();
        Date currentDate = DateUtils.parseDate(
                DateUtils.format(date, YYYY_MM_DD.toPattern()),
                YYYY_MM_DD.toPattern());

        calendar.setTimeInMillis(currentDate.getTime() + (DAY_TIME_NUMBER * 1)
                - 1);
        return calendar.getTime();
    }

    /**
     * 获取几天前或几天后的凌晨日期
     * 
     * @param number
     *            若为正整数则获取几天后的日期，反之后去几天前的日期
     * 
     * @return 日期，例：2012-01-01 00:00:00
     * @throws ParseException
     */
    public static Date getDateStartByNumber(int number, Date date)
            throws ParseException {
        Calendar calendar = Calendar.getInstance();
        Date currentDate = DateUtils.parseDate(
                DateUtils.format(date, YYYY_MM_DD.toPattern()),
                YYYY_MM_DD.toPattern());
        calendar.setTimeInMillis(currentDate.getTime()
                + (DAY_TIME_NUMBER * number));
        return calendar.getTime();
    }

    /**
     * 获取几天前或几天后的午夜日期
     * 
     * @param number
     *            若为正整数则获取几天后的日期，反之后去几天前的日期
     * 
     * @return 日期，例：2012-01-01 23:59:59
     * @throws ParseException
     */
    public static Date getDateEndByNumber(int number, Date date)
            throws ParseException {
        Calendar calendar = Calendar.getInstance();
        Date currentDate = DateUtils.parseDate(
                DateUtils.format(date, YYYY_MM_DD.toPattern()),
                YYYY_MM_DD.toPattern());
        calendar.setTimeInMillis(currentDate.getTime()
                + (DAY_TIME_NUMBER * (number + 1)) - 1);
        return calendar.getTime();
    }

    /**
     * 获取几天前或几天后的凌晨日期
     * 
     * @param number
     *            若为正整数则获取几天后的日期，反之后去几天前的日期
     * 
     * @return 日期，例：2012-01-01 00:00:00
     * @throws ParseException
     */
    public static Date getDateStartByNumber(int number) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        Date currentDate = DateUtils.parseDate(
                DateUtils.format(calendar.getTime(), YYYY_MM_DD.toPattern()),
                YYYY_MM_DD.toPattern());
        calendar.setTimeInMillis(currentDate.getTime()
                + (DAY_TIME_NUMBER * number));
        return calendar.getTime();
    }

    /**
     * 获取几天前或几天后的午夜日期
     * 
     * @param number
     *            若为正整数则获取几天后的日期，反之后去几天前的日期
     * 
     * @return 日期，例：2012-01-01 23:59:59
     * @throws ParseException
     */
    public static Date getDateEndByNumber(int number) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        Date currentDate = DateUtils.parseDate(
                DateUtils.format(calendar.getTime(), YYYY_MM_DD.toPattern()),
                YYYY_MM_DD.toPattern());
        calendar.setTimeInMillis(currentDate.getTime()
                + (DAY_TIME_NUMBER * (number + 1)) - 1);
        return calendar.getTime();
    }

    /**
     * 获取当前月份（1月=1,2月=3以此类推）
     * 
     * @return 返回数字类型的月份
     */
    public static int getCurrentMonth() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当前月份（1月=1,2月=3以此类推）
     * 
     * @return 返回数字类型的月份
     */
    public static int getCurrentMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当前年份
     * 
     * @return 返回数字类型的年份
     */
    public static int getCurrentYear() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取当前年份
     * 
     * @return 返回数字类型的年份
     */
    public static int getCurrentYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取指定日期的月份（1月=1,2月=3以此类推）
     * 
     * @return 返回数字类型的月份
     */
    public static int getDateMonth(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);

        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当前是几号（1号：1,2号：2以此类推）
     * 
     * @return
     */
    public static int getCurrentDay() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.DATE);
    }

    /**
     * 获取指定的日期是几号（1号：1,2号：2以此类推）
     * @param time
     * @return
     */
    public static int getDateDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);

        return calendar.get(Calendar.DATE);
    }

    /**
     * 返回当前日期是星期几，（周一：1，周二：2，周三：3，周四：4，周五：5，周六：6，周日：0）
     * 
     * @return 返回数字类型的星期数
     */
    public static int getCurrentWeek() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * 返回给定日期是星期几，（周一：1，周二：2，周三：3，周四：4，周五：5，周六：6，周日：0）
     * 
     * @return 返回数字类型的星期数
     */
    public static int getCurrentWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * 返回当前日期第几周
     * 
     * @return 返回数字类型的周数
     */
    public static int getNumberOfWeeks(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**可接受的日期格式，必须由大到小（日期+时分秒>只有日期）排*/
    private static String[] parsePatterns = new String[] {
            "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd",
            "yyyy/MM/dd" };

    public static Date parseDate(String dateStr) throws ParseException {
        if (dateStr == null || StringUtils.isEmpty(dateStr)
                || "".equals(dateStr.trim())) {
            return null;
        }
        return org.apache.commons.lang.time.DateUtils.parseDate(dateStr.trim(),
                parsePatterns);
    }

    /**
     * @param time
     * @param type
     * @return
     */
    public static Date truncate(Date time, int type) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(type, 0);
        return calendar.getTime();
    }

    /**
     * 验证字符串是否符合日期格式
     * @param dateStr
     * @return
     */
    public static boolean isValidDateStr(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return false;
        }
        try {
            DateUtils.parseDate(dateStr);
        } catch (ParseException e) {
            return false;
        }
        return true;
    }

    public static Date getLatestDate(Date date1, Date date2) {

        if (date1 == null)
            return date2;
        if (date2 == null)
            return date1;

        if (date1.after(date2)) {
            return date1;
        } else {
            return date2;
        }
    }

    public static Date getMonthFirstDay(Date date) {

        //获取前月的第一天
        Calendar calendar = Calendar.getInstance();//获取当前日期
        calendar.setTime(date);

        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    public static Date getMonthLastDay(Date date) {

        //获取前月的第一天
        Calendar calendar = Calendar.getInstance();//获取当前日期
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH,
                calendar.getActualMaximum(Calendar.DAY_OF_MONTH));

        return calendar.getTime();
    }

    public static void main(String[] args) throws ParseException {

        // 第一个参数大，第二个参数小，返回false
        //        System.out.println(DateUtils.isOvertime(new Date(),
        //                DateUtils.getDateEndByNumber(-1)));

        //	    System.out.println(DateUtils.isOvertime(DateUtils.getDateEndByNumber(-1), "yyyy-MM-dd HH:mm:ss"));

        //        System.out.println(DateUtils.getNumberOfWeeks(new Date()));

        //        Date startDate = DateUtils.parseDate("2015-10-20", "yyyy-MM-dd");
        //        Date endDate = DateUtils.parseDate("2015-10-20", "yyyy-MM-dd");
        //        System.out.println(!DateUtils.isOvertime(startDate, endDate));
        //        System.out.println(DateUtils.getDataStrByFormat(DateUtils.parseDate("2015-08-20", "yyyy-MM-dd"), "M"));

        Date startActivedDate = DateUtils.parseDate("2015-10-11", "yyyy-MM-dd");
        Date endActivedDate = DateUtils.parseDate("2015-10-20", "yyyy-MM-dd");

        Date startCalcActivedDate = null;
        Date endCalcActiveDate = null;

        while (true) {

            if (!DateUtils.isOvertime(endActivedDate, startActivedDate)) {

                startCalcActivedDate = DateUtils.getDateStart(startActivedDate);
                endCalcActiveDate = DateUtils.getDateEnd(startActivedDate);

                System.out.println(DateUtils.format(startCalcActivedDate,
                        "yyyy-MM-dd HH:mm:ss"));
                System.out.println(DateUtils.format(endCalcActiveDate,
                        "yyyy-MM-dd HH:mm:ss"));

                startActivedDate = DateUtils.getDateByDay(startActivedDate, 1);
            } else {
                break;
            }

        }
    }
}
